package com.mhc.haval.service.impl;

import com.mhc.haval.api.dto.StaffRoleDTO;
import com.mhc.haval.bo.RoleBO;
import com.mhc.haval.constant.MsgCodeEnum;
import com.mhc.haval.constant.RoleStatusEnum;
import com.mhc.haval.dal.mapper.ext.StaffRoleExtMapper;
import com.mhc.haval.dal.model.FuncDO;
import com.mhc.haval.dal.model.RoleDO;
import com.mhc.haval.dal.model.RoleFuncDO;
import com.mhc.haval.dal.query.RoleQuery;
import com.mhc.haval.exception.HavalCommonException;
import com.mhc.haval.manager.*;
import com.mhc.haval.service.RoleService;
import com.mhc.haval.vo.FuncVO;
import com.mhc.haval.vo.RoleFuncVO;
import com.mhc.haval.vo.StaffRoleVO;
import com.subaru.common.util.BeanCopierUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author Churry
 * @create 2017-08-23 13:37
 **/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleManager roleManager;
    @Autowired
    private FuncManager funcManager;
    @Autowired
    private RoleFuncManager roleFuncManager;
    @Autowired
    private StaffRoleExtMapper staffRoleExtMapper;

    /**
     * 获取角色列表
     *
     * @return
     */
    @Override
    public List<RoleDO> getRoleList() throws HavalCommonException {
        try {
            //查询条件为status！=-1即非已删除角色，即获取所有的角色
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.createCriteria().andStatusNotEqualTo(RoleStatusEnum.DELETED.getCode());
            return roleManager.selectByQuery(roleQuery);
        } catch (Exception e) {
            log.error("获取角色列表失败", e);
            throw new HavalCommonException(MsgCodeEnum.QUERY_ROLE_LIST_FAIL);
        }
    }

    /**
     * 获取角色详情
     *
     * @return
     */
    @Override
    public RoleBO getRoleDetail(Long roleId) throws HavalCommonException {
        Optional<Long> roleIdOptional = Optional.ofNullable(roleId);
        if (roleIdOptional.isPresent()) {
            try {
                RoleDO roleDO = roleManager.selectByPrimaryKey(roleId);
                RoleBO roleBO = BeanCopierUtil.convert(roleDO, RoleBO.class);
                //获取角色拥有的权限
                List<FuncVO> funcVOS = new ArrayList<>();
                for (FuncDO funcDO : funcManager.selectByRoleId(roleId)) {
                    FuncVO func = BeanCopierUtil.convert(funcDO, FuncVO.class);
                    funcVOS.add(func);
                }
                roleBO.setFuncList(funcVOS);
                return roleBO;
            } catch (Exception e) {
                log.error("获取角色详情失败", e);
                throw new HavalCommonException(MsgCodeEnum.QUERY_ROLE_DETAIL_FAIL);
            }
        } else {
            throw new HavalCommonException(MsgCodeEnum.ROLE_ID_ISNULL);
        }
    }


    /**
     * 新增角色详情
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean addRoleDetail(RoleBO role, List<RoleFuncVO> roleFuncList) throws HavalCommonException {
        Optional<RoleBO> roleOptional = Optional.ofNullable(role);
        if (roleOptional.isPresent()) {
            RoleDO roleDO = BeanCopierUtil.convert(role, RoleDO.class);
            try {
                roleManager.insertSelective(roleDO);
            } catch (Exception e) {
                log.error("新增角色详情失败", e);
                throw new HavalCommonException(MsgCodeEnum.INSERT_ROLE_FAIL);
            }
            //插入数据库后，角色id从空值变成新生成的id
            role.setRoleId(roleDO.getRoleId());
            //更新数据，此时角色-功能关联关系才有完整数据
            List<RoleFuncVO> compRoleFuncList = new ArrayList<>();
            for (RoleFuncVO roleFuncVO : roleFuncList) {
                roleFuncVO.setRoleId(role.getRoleId());
                compRoleFuncList.add(roleFuncVO);
            }
            //调用的方法已经自行抛出异常，所以这里不抛出
            saveRoleFuncs(compRoleFuncList);
            return true;
        } else {
            throw new HavalCommonException(MsgCodeEnum.ROLE_ISNULL);
        }
    }

    /**
     * 修改角色详情
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateRoleDetail(RoleBO role, List<RoleFuncVO> roleFuncList) throws HavalCommonException {
        Optional<RoleBO> roleOptional = Optional.ofNullable(role);
        if (roleOptional.isPresent()) {
            RoleDO roleDO = BeanCopierUtil.convert(role, RoleDO.class);
            try {
                roleManager.updateByPrimaryKeySelective(roleDO);
            } catch (Exception e) {
                log.error("更新角色详情失败", e);
                throw new HavalCommonException(MsgCodeEnum.UPDATE_ROLE_FAIL);
            }
            //删除数据库中现存的角色功能关联信息
            try {
                for (RoleFuncDO preRoleFuncDO : roleFuncManager.selectByRoleId(role.getRoleId())) {
                    roleFuncManager.deleteByPrimaryKey(preRoleFuncDO);
                }
            } catch (Exception e) {
                log.error("删除现存的角色-功能关联失败", e);
                throw new HavalCommonException(MsgCodeEnum.DELETE_ROLE_FUNC_FAIL);
            }
            //调用的方法已经自行抛出异常，所以这里不抛出
            saveRoleFuncs(roleFuncList);
            return true;
        } else {
            throw new HavalCommonException(MsgCodeEnum.ROLE_ISNULL);
        }
    }

    /**
     * 新增一条角色功能关联信息
     *
     * @param roleFuncVO 角色功能关联信息
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveRoleFunc(RoleFuncVO roleFuncVO) throws HavalCommonException {
        Optional<RoleFuncVO> roleFuncDOOptional = Optional.ofNullable(roleFuncVO);
        if (roleFuncDOOptional.isPresent()) {
            RoleFuncDO roleFuncDO = BeanCopierUtil.convert(roleFuncVO, RoleFuncDO.class);
            try {
                roleFuncManager.insertSelective(roleFuncDO);
            } catch (Exception e) {
                log.error("新增角色-功能关联失败", e);
                throw new HavalCommonException(MsgCodeEnum.INSERT_ROLE_FUNC_FAIL);
            }
        } else {
            throw new HavalCommonException(MsgCodeEnum.ROLE_FUNC_ISNULL);
        }
    }

    /**
     * 新增多条角色功能关联信息，循环调用保存一条的方法
     *
     * @param roleFuncVOS 角色功能关联信息
     * @return
     */
    public void saveRoleFuncs(List<RoleFuncVO> roleFuncVOS) throws HavalCommonException {
        try {
            //保存数据
            for (RoleFuncVO roleFuncVO : roleFuncVOS) {
                saveRoleFunc(roleFuncVO);
            }
        } catch (Exception e) {
            throw new HavalCommonException(e);
        }
    }

    @Override
    public Boolean deleteRole(Long staffId, Long roleId) throws HavalCommonException {
        Optional<Long> roleIdOptional = Optional.ofNullable(roleId);
        if (roleIdOptional.isPresent()) {
            try {
                RoleDO roleDO = roleManager.selectByPrimaryKey(roleId);
                roleDO.setStatus(RoleStatusEnum.DELETED.getCode());
                roleDO.setModifier(staffId);
                roleManager.updateByPrimaryKeySelective(roleDO);
            } catch (Exception e) {
                log.error("删除角色失败", e);
                throw new HavalCommonException(MsgCodeEnum.DELETE_ROLE_FAIL);
            }
            return true;
        } else {
            throw new HavalCommonException(MsgCodeEnum.ROLE_ID_ISNULL);
        }
    }


    /**
     * 根据角色code查找用户
     *
     * @param roleCode
     * @return
     * @throws Exception
     */
    @Override
    public List<StaffRoleVO> selectStaffByRole(String roleCode) throws HavalCommonException{
        log.info("当前角色为：" + roleCode + ",开始查询该角色下的所属用户...");
        /**通过角色查询该角色下的所属用户**/
        List<StaffRoleVO> staffList = staffRoleExtMapper.queryStaffByRole(roleCode);
        log.info("查询成功，当前角色下的所属用户为：" + staffList);
        return staffList;
    }

}
